import { ref, computed, watch, nextTick } from 'vue'
import { defineStore } from 'pinia'
import {
  getUserInfo,
  getTeachingInfo as getTeachingInfoFromServer,
  getCourseId,
  postUserInfo,
  getRoleByTeacherId,
  postTeachingInfo
} from '@/apis'

import { computedStageId } from '@/utils'

import { defaultTime } from '@/views/target-boost/utils'
import router from '@/router'
import { ElMessage } from 'element-plus'
import { useRoute } from 'vue-router'
import _ from 'lodash'
import { useTaskStore } from './task'
import { subjectMap } from '@/constants'

export const ROLE_ENUM = {
  StoreManager: 'role|1012', // 店长
  RegionalCommissioner: 'role|1013', // 区域专员
  HeadTeacher: 'role|1014', // 班主任
  Planner: 'role|1015' // 规划师
}
// 爱学班角色
const SMART_ROOM_ROLES = [ROLE_ENUM.StoreManager, ROLE_ENUM.Planner]

// 校务管理员,之后合并代码可以放进Map中
const SchoolAdministrator = 'role|1007'
export const useAuthStore = defineStore(
  'auth',
  () => {
    const route = useRoute()

    const userInfo = ref({
      sessionId: '',
      sessionName: '',
      userId: '',
      userName: '',
      platform: '',
      userType: '',
      school_id: '',
      school_name: '',
      classroomTree: [],
      // 学科列表和班级列表是profileCard组件赋值，工作台的数据依赖这两List
      subjectList: [],
      classroomList: []
    })

    const setUserInfo = param => {
      userInfo.value = param
    }

    const onlyTeacher = ref(false)
    const setOnlyTeacher = data => {
      onlyTeacher.value = data
    }

    // 当前的用户权限对象
    const nowGlobalRole = ref(null)
    const setNowGlobalRole = param => {
      nowGlobalRole.value = param
    }
    const roles = ref([])
    const filteredRoles = ref([])
    const setRoles = param => {
      roles.value = param || []
      filteredRoles.value = _.unionBy(param || [], 'role_code')
    }

    const nowIsSmartRoomCode = computed(() => {
      return SMART_ROOM_ROLES.includes(nowGlobalRole.value?.role_code)
    })

    // 是否来自阅卷跳转并且有校务管理员角色
    const isFromExam = computed(() => {
      const e = (roles.value || []).find(item => {
        return item.role_code === SchoolAdministrator
      })
      return route.query.fromSystem === 'examination' && e
    })

    // 缓存当前选中的班级和时间段
    const selectedClass = ref('')
    const classType = ref('')
    const currentGradeNum = ref('')
    const currentGradeId = ref('')
    const classId = ref('')
    const selectedTime = ref(defaultTime())

    // 教师 班级 年级 科目源数据
    const originGscList = ref([])
    const allGradeList = ref()

    // 获取教师 班级 年级 科目 信息
    const getUserInfoFun = async () => {
      const res = await getUserInfo({
        teacher_id: userInfo.value.userId,
        role_code: nowGlobalRole.value.role_code
      })
      console.log('获取教师', res.data)
      const {
        admini_and_teaching_class,
        section_subject_list,
        targeted_class,
        zhixi_class
      } = res.data
      setUserInfo({
        ...userInfo.value
      })
      let gradeList = []
      let classList = []
      let subjectList = []

      originGscList.value = admini_and_teaching_class || []

      admini_and_teaching_class?.forEach(param => {
        // 保存年级信息
        if (
          gradeList.findIndex(item => item.value === param.grade_num) === -1
        ) {
          gradeList.push({
            value: param.grade_num,
            label: param.grade_name,
            id: param.grade_id
          })
        }
        classList.push({
          value: param.id,
          label: param.class_name,
          grade_id: param.grade_id,
          grade_num: param.grade_num,
          subjectList: (param.subject_list || []).map(subject => subject.num),
          is_target: false
        })
      })

      targeted_class?.forEach(param => {
        classList.push({
          value: param.id,
          label: param.class_name,
          grade_id: param.grade_id || -1,
          grade_num: param.grade_num || -1,
          grade_name: param.grade_name || '',
          subjectList: [param.subject_num],
          is_target: true
        })
      })
      zhixi_class?.forEach(param => {
        classList.push({
          value: param.id,
          label: param.class_name,
          grade_id: param.grade_id || -1,
          grade_num: param.grade_num || -1,
          subjectList: (param.subject_list || []).map(subject => subject.num),
          is_target: false
        })
      })

      subjectList = section_subject_list
        ?.filter(subject => subject.num > 0)
        .map(subject => ({
          value: subject.num,
          label: subject.name
        }))

      allGradeList.value = gradeList
      return {
        gradeList,
        classList,
        subjectList
      }
    }
    // 获取学校的信息,userType 2 是老师 1 是学生
    const getSchoolInfo = async () => {
      const res = await postUserInfo({
        personId: userInfo.value.userId,
        userType: 2
      })
      console.log(res.data)
      if (res.code === 100200) {
        setUserInfo({
          ...userInfo.value,
          school_id: res.data.school_id,
          school_name: res.data.school_name,
          organ_type: res.data.organ_type,
          phone: res.data.phone
        })
      } else {
        ElMessage.error(res.msg)
      }
    }
    const flattenGscList = computed(() => {
      const tempList = originGscList.value
      const flatList = []
      for (let index = 0; index < tempList.length; index++) {
        const subjectList = tempList[index].subject_list || []
        for (let index1 = 0; index1 < subjectList.length; index1++) {
          const ele = {
            ...tempList[index],
            subject_num: subjectList[index1].num,
            subject_name: subjectList[index1].name
          }
          flatList.push(ele)
        }
      }
      return flatList
    })

    /* 靶向提升页面用到的教学信息 begin */
    // 感觉是全局通用的，如果是，后续可考虑和上面那些统一
    const tbAdminAndTeachingClassList = ref([])
    const tbTargetClassList = ref([])
    const tbSubjectList = ref([])
    const smartRoomClassList = ref([])
    const resetClassList = () => {
      tbAdminAndTeachingClassList.value = []
      tbTargetClassList.value = []
      tbSubjectList.value = []
      smartRoomClassList.value = []
      selectedClass.value = ''
      classType.value = ''
      currentGradeNum.value = ''
    }

    const tbSubjectListInLabelValue = computed(() =>
      tbSubjectList.value
        ?.filter(subject => subject.num > 0)
        .map(subject => ({
          value: subject.num,
          label: subject.name
        }))
        .sort((s1, s2) => s1.value - s2.value)
    )

    // 更新全局学科列表
    function updateGlobalSubjectData(data, subjectId) {
      globalSubjectList.value = data.section_subject_list.filter(v =>
        Object.keys(subjectMap).includes(v.subject_num.toString())
      )
      const e = globalSubjectList.value.find(
        item => item.subject_num === Number(subjectId)
      )
      if (subjectId && e) {
        nowGlobalSubjectId.value = e.subject_num
        return
      }
      nowGlobalSubjectId.value = globalSubjectList.value?.some(
        s => s?.subject_num === 2
      )
        ? 2
        : globalSubjectList.value[0]?.subject_num
    }

    async function getPermission() {
      if (!userInfo.value.school_id) {
        await getSchoolInfo()
      }
      const [roleRes, teachingInfoRes] = await Promise.all([
        getRoleByTeacherId({
          teacherId: userInfo.value.userId,
          schoolId: userInfo.value.school_id
        }),
        postTeachingInfo({
          teacher_id: userInfo.value.userId,
          schoolId: userInfo.value.school_id
        })
      ])

      const subjectList =
        teachingInfoRes.data
          ?.flatMap(item => item.subject_list)
          .filter(
            (item, index, self) =>
              index === self.findIndex(t => t?.code === item?.code)
          ) || []

      // 无角色无科目用户无法登录
      if (!roleRes?.data && !subjectList.length) {
        ElMessage.error('当前账号没有角色')
        return false
      }
      setRoles(roleRes.data)
      setOnlyTeacher(!roleRes.data && subjectList.length)

      if (isFromExam.value) {
        const e = (roleRes.data || []).find(item => {
          return item.role_code === SchoolAdministrator
        })
        setNowGlobalRole(e)
      } else {
        // 无任教科目但有角色，则默认角色为任课老师
        if (!subjectList.length) {
          setNowGlobalRole(roleRes.data[0])
        } else {
          setNowGlobalRole({ role_name: '任课老师', role_code: '' })
        }
      }

      return true
    }

    async function handleLoginInfo(data) {
      resetAllStates()
      setUserInfo(data)

      if (await getPermission()) {
        const hasSubject = await getGlobalSubjectList(
          nowGlobalRole.value.role_code
        )
        if (!hasSubject) {
          ElMessage.error('当前账号学校没有开设学科')
          return
        }
        ElMessage.success('登录成功')
        console.log(nowGlobalRole.value.role_code)
        if (data.fromSystem === 'examination') {
          return
        } else {
          router.push('/')
        }
      }
    }

    async function getTeachingInfo(roleCode = '') {
      const { code, msg, data } = await getTeachingInfoFromServer(
        userInfo.value.userId,
        roleCode
      )
      if (code !== 100200 && msg !== 'success') {
        return
      }
      // fix: 读不到值，被覆盖为空，导致 school_id 赋值为 undefined 程序受影响
      // 不清楚原逻辑，暂保留
      let id =
        data.admini_and_teaching_class?.[0].school_id ||
        data.zhixi_class?.[0].school_id
      id && (userInfo.value.school_id = id)
      // userInfo.value.school_id =
      //   data.admini_and_teaching_class?.[0].school_id ||
      //   data.zhixi_class?.[0].school_id
      tbAdminAndTeachingClassList.value = data.admini_and_teaching_class
      tbTargetClassList.value = data.targeted_class
      smartRoomClassList.value = data.zhixi_class || []
      tbSubjectList.value = data.subject_list
      globalSubjectList.value =
        data?.section_subject_list.filter(v =>
          Object.keys(subjectMap).includes(v.subject_num.toString())
        ) || []

      let hasSame = globalSubjectListYouSee.value[
        3 - nowGlobalStageId.value
      ].value.findIndex(item => {
        return item.subject_num === nowGlobalSubjectId.value
      })
      const taskStore = useTaskStore()
      // 有一样的不用处理
      if (hasSame >= 0) {
        return
      }
      // 没有一样的，试找不同年级的同科目
      let hasSubject
      for (let item of globalSubjectListYouSee.value) {
        hasSubject = item.value.find(item => {
          return item.subject_num === nowGlobalSubjectId.value
        })
        if (hasSubject) {
          changeGlobalInfo(hasSubject.subject_num, hasSubject.section_num)
          nextTick(() => {
            taskStore.getBasketQuestionInfo()
          })
          return
        }
      }

      // 有年级但没有科目，选择该年级的第一个科目
      let hasStage = data.section_subject_list.findIndex(item => {
        return item.section_num === nowGlobalStageId.value
      })
      if (hasStage >= 0) {
        changeGlobalInfo(
          globalSubjectListYouSee.value[3 - nowGlobalStageId.value].value[0]
            .subject_num,
          nowGlobalStageId.value
        )
        nextTick(() => {
          taskStore.getBasketQuestionInfo()
        })
      }
      // 都没,找一个列表最前面的科目
      else {
        for (let item of globalSubjectListYouSee.value) {
          if (item.value.length > 0) {
            changeGlobalInfo(
              item.value[0].subject_num,
              item.value[0].section_num
            )
            nextTick(() => {
              taskStore.getBasketQuestionInfo()
            })
            return
          }
        }
      }
    }

    async function getAdminAndTeachingClassListOfSubject(subjectId) {
      const classTypeMap = {
        'class_category|1001': 1,
        'class_category|1002': 2
      }
      if (!tbAdminAndTeachingClassList.value?.length) return []
      const result = []
      // TODO 后续加上切换学校后处理多个学校的情况，目前暂时只取第一个学校的数据
      const [school] = tbAdminAndTeachingClassList.value
      console.log(school)
      school?.grade_list.forEach(grade => {
        const classList = grade.class_list.filter(cls => {
          if (subjectId === 0) {
            return true
          }
          if (!cls.subject_list) {
            return false
          }
          return cls?.subject_list.some(subject =>
            nowGlobalRole.value.role_code === ROLE_ENUM.HeadTeacher
              ? computedStageId(cls.grade_num) === nowGlobalStageId.value
              : subject.num === subjectId &&
                computedStageId(cls.grade_num) === nowGlobalStageId.value
          )
        })
        if (grade.grade_name === '八年级') {
          console.log(classList)
        }
        if (classList.length > 0) {
          result.push({
            value: grade.grade_num,
            label: grade.grade_name,
            grade_id: grade.grade_id,
            children: classList.map(cls => ({
              value: cls.id,
              label: cls.class_name,
              class_type: classTypeMap[cls.class_type]
            }))
          })
        }
      })
      console.log(result)
      return result
    }

    async function getTargetClassListOfSubject(subjectId) {
      console.log(tbTargetClassList?.value)
      if (subjectId === 0) {
        return tbTargetClassList.value
      }
      return tbTargetClassList?.value?.filter(
        v =>
          v.subject_num === subjectId &&
          computedStageId(v.grade_num) === nowGlobalStageId.value
      )
    }

    function getSmartZoomClassListOfSubject() {
      return (smartRoomClassList.value || []).filter(
        v => computedStageId(v.grade_num) === nowGlobalStageId.value
      )
    }

    async function getClassListOfSubject(subjectId) {
      const result = await getAdminAndTeachingClassListOfSubject(subjectId)
      const targetClass = await getTargetClassListOfSubject(subjectId)
      const zxClass = await getSmartZoomClassListOfSubject()
      if (targetClass?.length > 0) {
        console.log(targetClass)

        result.push({
          value: 0,
          label: '靶向班',
          children: targetClass.map(cls => ({
            value: cls.id,
            label: cls.class_name,
            grade_num: cls.grade_num,
            // 靶向班的类型全是3，如果其他接口要的参数不是这个的话，叫他们改（后端说的）
            class_type: 3,
            grade_id: cls.grade_id
          }))
        })
      }
      if (zxClass?.length) {
        result.push({
          value: '-1',
          label: '爱学班',
          children: zxClass.map(cls => ({
            value: cls.id,
            label: cls.grade_name + cls.class_name,
            grade_num: cls.grade_num,
            class_type: 4,
            grade_id: cls.grade_id
          }))
        })
      }
      return result
    }
    /* 靶向提升页面用到的教学信息 end */

    /* 全局学科切换 begin */
    const globalSubjectList = ref([])
    const nowGlobalSubjectId = ref(2)
    const nowGlobalStageId = ref(2)
    const nowGlobalCourseId = ref()

    const getAndChangeCourseId = async () => {
      const res = await getCourseId({
        subjectId: nowGlobalSubjectId.value,
        stageId: nowGlobalStageId.value
      })
      if (res && res.data) {
        nowGlobalCourseId.value = res.data.course_list[0].course_id
      }
    }
    watch(
      () => [nowGlobalSubjectId.value, nowGlobalStageId.value],
      async () => {
        await getAndChangeCourseId()
      }
    )

    const sortSubjectFn = (a, b) => {
      const codeA = a.subject_code.split('|')[1]
      const codeB = b.subject_code.split('|')[1]
      return codeA - codeB
    }

    const globalSubjectListYouSee = computed(() => {
      return [
        {
          key: 3,
          value: globalSubjectList.value
            ?.filter(subject => subject.section_num === 3)
            .sort(sortSubjectFn)
        },
        {
          key: 2,
          value: globalSubjectList.value
            ?.filter(subject => subject.section_num === 2)
            .sort(sortSubjectFn)
        },
        {
          key: 1,
          value: globalSubjectList.value
            ?.filter(subject => subject.section_num === 1)
            .sort(sortSubjectFn)
        }
      ]
    })

    function changeGlobalInfo(subjectId, stageId) {
      nowGlobalSubjectId.value = subjectId
      nowGlobalStageId.value = stageId
    }

    async function getGlobalSubjectList(roleCode = '') {
      console.log(roleCode)
      const { code, msg, data } = await getTeachingInfoFromServer(
        userInfo.value.userId,
        roleCode
      )
      if (code !== 100200 && msg !== 'success') {
        return false
      }
      console.log(data.section_subject_list)

      // 该账号的学校没有开设学科
      if (!data.section_subject_list) {
        return false
      }

      // 从阅卷跳转过来的取缓存的学段
      if (isFromExam.value) {
        updateGlobalSubjectData(data, route.query?.subjectId)
        const stage = Number(route.query?.stageId)
        nowGlobalStageId.value = globalSubjectList.value.some(
          item => item.section_num === stage
        )
          ? stage
          : globalSubjectList.value[0].section_num
      } else {
        updateGlobalSubjectData(data)
        // 如果有初中就设置为2，否则就拿第一个
        nowGlobalStageId.value = globalSubjectList.value.some(
          item => item.section_num === 2
        )
          ? 2
          : globalSubjectList.value[0].section_num
      }

      await getAndChangeCourseId()
      return true
    }
    /* 全局学科切换 end */
    // 重置所有状态
    // isExpired 是否过期重置
    const resetAllStates = (isExpired = false) => {
      userInfo.value = {
        sessionId: '',
        sessionName: '',
        userId: '',
        userName: '',
        platform: '',
        userType: '',
        school_id: '',
        classroomTree: [],
        subjectList: [],
        classroomList: []
      }

      onlyTeacher.value = false
      nowGlobalRole.value = null
      roles.value = []
      filteredRoles.value = []
      selectedClass.value = ''
      classType.value = ''
      currentGradeNum.value = ''
      classId.value = ''
      selectedTime.value = defaultTime()
      originGscList.value = []
      allGradeList.value = undefined

      resetClassList()

      globalSubjectList.value = []
      nowGlobalSubjectId.value = 2
      nowGlobalStageId.value = 2
      nowGlobalCourseId.value = undefined

      if (isExpired) {
        ElMessage.error('登录过期，请重新登录')
      }
    }

    return {
      userInfo,
      setUserInfo,
      getSchoolInfo,
      onlyTeacher,
      setOnlyTeacher,
      getUserInfoFun,
      getPermission,
      handleLoginInfo,
      selectedClass,
      classType,
      currentGradeNum,
      currentGradeId,
      nowGlobalRole,
      setNowGlobalRole,
      nowIsSmartRoomCode,
      roles,
      filteredRoles,
      setRoles,
      classId,
      resetClassList,
      selectedTime,
      flattenGscList,
      allGradeList,
      tbAdminAndTeachingClassList,
      tbTargetClassList,
      smartRoomClassList,
      tbSubjectList,
      tbSubjectListInLabelValue,
      getClassListOfSubject,
      getTeachingInfo,
      globalSubjectList,
      globalSubjectListYouSee,
      nowGlobalSubjectId,
      nowGlobalStageId,
      nowGlobalCourseId,
      changeGlobalInfo,
      getGlobalSubjectList,
      resetAllStates
    }
  },
  {
    persist: {
      paths: [
        'userInfo',
        'onlyTeacher',
        'selectedClass',
        'classType',
        'currentGradeNum',
        'currentGradeId',
        'nowGlobalRole',
        'roles',
        'classId',
        'flattenGscList',
        'allGradeList',
        'tbAdminAndTeachingClassList',
        'tbTargetClassList',
        'smartRoomClassList',
        'tbSubjectList',
        'tbSubjectListInLabelValue',
        'globalSubjectListYouSee',
        'globalSubjectList',
        'nowGlobalSubjectId',
        'nowGlobalStageId',
        'nowGlobalCourseId'
      ]
    }
  }
)
// 不同标签从local中更新学段和学科
document.addEventListener('visibilitychange', function () {
  if (document.visibilityState === 'visible') {
    let auth = localStorage.getItem('auth')
    if (auth) {
      auth = JSON.parse(auth)
      const { nowGlobalStageId, nowGlobalSubjectId } = auth
      const authStore = useAuthStore()
      if (
        nowGlobalStageId != authStore.nowGlobalStageId ||
        nowGlobalSubjectId != authStore.nowGlobalSubjectId
      ) {
        const taskStore = useTaskStore()
        authStore.changeGlobalInfo(nowGlobalSubjectId, nowGlobalStageId)
        taskStore.getBasketQuestionInfo()
      }
    }
  }
})
